package com.woniu.product.controller;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniu.model.Result;
import com.woniu.product.dto.GoodsDto;
import com.woniu.product.dto.GoodsListDto;
import com.woniu.product.dto.VenueAdminDto;
import com.woniu.product.form.*;
import com.woniu.product.model.Goods;
import com.woniu.product.param.*;
import com.woniu.product.service.GoodsService;
import com.woniu.util.FileUtil;
import com.woniu.util.JwtUtil;
import com.woniu.util.OSSUtil;
import com.woniu.util.RedisUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author 杜岷芫
 * @since 2024年07月12日
 */
@RestController
@RequestMapping("/goods")
@Api(tags = "商城商品接口")
public class GoodsController {
    @Resource
    private GoodsService goodsService;
    @Resource
    private RedisUtil redisUtil;

    /**
     * 新增商品
     *
     * @param form
     * @return
     * @throws Exception
     */
    @PostMapping("/insertGoods")
    @ApiOperation("新增商品")
    public Result<?> insertGoods(@RequestBody AddGoodsForm form) throws Exception {
        goodsService.insertGoods(BeanUtil.toBean(form, AddGoodsParam.class));
        return Result.getResult().setMsg("新增商品成功").setCode(200);

    }

    /**
     * 通过一个商品ID查询一个商品回去
     *
     * @param id ：商品id
     * @return 一个商品
     */
    @GetMapping("/byId/{id}")
    public Result<GoodsDto> byId(@PathVariable("id") Integer id) throws Exception {
        Goods goods = goodsService.getById(id);
        return Result.getResult(GoodsDto.class).setData(BeanUtil.toBean(goods, GoodsDto.class));

    }

    /**
     * 通过一个商品ID查询一个商品回去
     *
     * @param id ：商品id
     * @return 一个商品
     */
    @GetMapping("/selectGoodsById")
    public Result<GoodsDto> selectGoodsById(@RequestParam(required = true) Integer id) throws Exception {
        Goods goods = goodsService.getById(id);
        return Result.getResult(GoodsDto.class).setData(BeanUtil.toBean(goods, GoodsDto.class));

    }

    /**
     * 上架商品
     *
     * @param goodsId 商品id
     * @return
     * @throws Exception
     */
    @GetMapping("/enable")
    @ApiOperation(value = "上架商品")
    public Result enable(Integer goodsId) throws Exception {
        goodsService.enable(goodsId);


        return Result.getResult(null).setCode(200).setMsg("上架成功");
    }

    /**
     * 下架商品
     *
     * @param goodsId
     * @return
     * @throws Exception
     */
    @GetMapping("/disable")
    @ApiOperation("下架商品")
    public Result disable(Integer goodsId) throws Exception {
        goodsService.disable(goodsId);
        return Result.getResult().setCode(200).setMsg("下架成功");
    }

    /**
     * 添加商品到购物车
     *
     * @param GoodsId 商品id
     * @param num     商品数量
     * @param token
     * @return
     * @throws Exception
     */
    @PostMapping("/addShopping")
    @ApiOperation("添加商品到购物车")
    public Result addShopping(@RequestParam("GoodsId") Integer GoodsId, @RequestParam("num") Integer num, @RequestHeader String token) throws Exception {
        String refreshToken = redisUtil.get(token);
        Integer userId = (Integer) JwtUtil.parseUserToken(token).get("userId");
        AddShoppingParam param = new AddShoppingParam();
        param.setGoodsId(GoodsId);
        param.setNum(num);
        param.setUserId(userId);
        goodsService.addShopping(param);
        return Result.getResult(null).setMsg("添加成功").setCode(200);
    }

    @PostMapping("/delShopping")
    @ApiOperation("删除购物车的商品")
    public Result delShopping(@RequestParam("GoodsId") Integer GoodsId, @RequestParam("num") Integer num, @RequestHeader String token) throws Exception {
        String refreshToken = redisUtil.get(token);
        VenueAdminDto venueAdminDto = JSONUtil.toBean(JSONUtil.toJsonStr(JwtUtil.getVenueAdmin(refreshToken)), VenueAdminDto.class);
        AddShoppingParam param = new AddShoppingParam();
        param.setUserId(venueAdminDto.getUserId());
        param.setNum(num);
        param.setGoodsId(GoodsId);
        goodsService.delShopping(param);
        return Result.getResult(null).setCode(200).setMsg("删除成功");
    }

    @PostMapping("/updateShopping")
    @ApiOperation("修改购物车商品数量")
    public Result updateShopping(@RequestBody UpdateShoppingForm form, @RequestHeader String token) throws Exception {
        String refreshToken = redisUtil.get(token);
        VenueAdminDto venueAdminDto = JSONUtil.toBean(JSONUtil.toJsonStr(JwtUtil.getVenueAdmin(refreshToken)), VenueAdminDto.class);
        UpdateShoppingParam param = BeanUtil.toBean(form, UpdateShoppingParam.class);
        param.setUserId(venueAdminDto.getUserId());
        goodsService.updateShopping(param);
        return Result.getResult(null).setMsg("修改成功").setCode(200);
    }

    /**
     * 商品图片修改
     *
     * @param form
     * @return
     * @throws Exception
     */
    @PostMapping("/updateImage")
    @ApiOperation("修改商品图片")
    public Result updateImage(UpdateImageForm form) throws Exception {
        // @RequestBody不能加，本次请求传了文件的，不加该注解;文件只能用表单参数
        if (!FileUtil.isImageFile(form.getImage().getInputStream())) {
            throw new Exception("文件类型有误，请检查");
        }

        String oldname = form.getImage().getOriginalFilename();
        //获取上传文件的原始文件名。

        String substring = oldname.substring(oldname.lastIndexOf("."));
        //获取上传文件的后缀名。

        String filename = new Snowflake(1, 1).nextIdStr();
        //生成一个雪花作为文件名

        String filePath = OSSUtil.uploadFile(form.getImage().getInputStream(), filename + substring, "zenghongwei");
        //调用 OSSUtil 工具类的 uploadFile() 方法，将上传的文件保存到阿里云 OSS 存储中。该方法接受文件的输入流、文件名和存储桶名称作为参数，并返回上传文件的路径。

        System.out.println(filePath + "上传到oss的名字");
        UpdateImageParam param = BeanUtil.toBean(form, UpdateImageParam.class);

        param.setGoodsImage(filePath);
        //传文件的路径设置到 BookInsertParam 对象中，作为图书的封面图片路径。

        System.out.println(filePath + "存到数据库的名字");

        goodsService.updateImage(param);

        return Result.getResult(null).setMsg("修改成功").setCode(200);
    }

    @PostMapping("/updateGoods")
    @ApiOperation("修改商品信息")
    public Result updateGoods(UpdateGoodsForm form) throws Exception {
        goodsService.updateGoods(BeanUtil.toBean(form, UpdateGoodsParam.class));
        return Result.getResult(null).setCode(200).setMsg("修改成功");
    }

    @GetMapping("/pageGoods")
    @ApiOperation("分页查询商品")
    public Result pageGoods(PageGoodsForm form) throws Exception {
        Page<Goods> goodsPage = goodsService.pageGoods(BeanUtil.toBean(form, PageGoodsParam.class));

        return Result.getResult(Page.class).setMsg("分页查询成功").setCode(200).setData(goodsPage);
    }

    /**
     * 通过多个商品ID查询商品集合回去
     * @param id
     * @return
     * @throws Exception
     */
    @PostMapping("/listById")
    @ApiOperation(value = "通过多个商品ID查询商品集合回去")
    public Result<List<GoodsListDto>> listById(@RequestBody Set<Integer> id) throws Exception {
        // 查询商品
        List<Goods> goodsList = goodsService.listByIds(id);

        // 转换为DTO
        List<GoodsListDto> goodsListDtos = goodsList.stream()
                .map(goods -> {
                    GoodsListDto dto = new GoodsListDto();
                    BeanUtils.copyProperties(goods, dto); // 复制属性
                    return dto;
                })
                .collect(Collectors.toList());

        // 创建结果对象
        Result<List<GoodsListDto>> result = Result.getListResult(GoodsListDto.class);
        result.setData(goodsListDtos);

        return result;
    }
}
